perm filename IEXTRA.PAS[EAL,HE] blob sn#704687 filedate 1983-03-25 generic text, type C, neo UTF8
COMMENT ⊗   VALID 00005 PAGES
C REC  PAGE   DESCRIPTION
C00001 00001
C00002 00002	(* ppArmError is called by msgDispatch & moveEnd *)
C00005 00003	(* doSay called by Interp *)
C00010 00004	(* doArmmagic called by Interp *)
C00014 00005	(* doFloat called by Interp *)
C00017 ENDMK
C⊗;
(* ppArmError is called by msgDispatch & moveEnd *)

procedure ppArmError(err: errortypes; angle: integer);
 begin
 if err = nopower then
   begin pp20('arm power not on    ',16); ppLine; end
  else if err = devbusy then
   begin pp20('device currently in ',20); pp5('use  ',4); ppLine end
  else
   begin
   case err of
srvdead:   pp10('servo dead',10);
adcdead:   pp10('a/d error ',9);
panicb:    pp20('panic button pushed ',19);
exjtfc:    begin pp20('excessive joint forc',20); ppChar('e'); end;
timout:    pp10('time out  ',8);
paslim:    pp20('joint out of range  ',18);
badpot:    pp20('bad pot on PUMA     ',15);
noarmsol:  pp20('No arm solution     ',16);
nocart:    begin pp20('No Cartesian path ex',20); pp20('ists between these p',20);
		 pp20('ath points.         ',11) end;
timerr:    begin pp20('Specified motion tim',20); pp20('e exceeds capabiliti',20);
		 pp5('es.  ',3) end;
durerr:    begin pp20('Motion overly constr',20); pp20('ained, will ignore g',20);
		 pp20('lobal time constrain',20); pp5('t.   ',2) end;
toolong:   begin pp20('Maximum segment time',20); pp20(' allowed is 32.2 sec',20);
		 pp5('onds.',5) end;
badparm:   pp20('Bad Magic Parameter ',19);
unkmess:   begin pp20('Unknown Message Type',20); pp20(' received from AL!  ',18) end;
nozind:    begin pp20('No Zero Index found ',20); pp20('( PUMA Encoder )    ',16) end;
baddev:    begin pp20('Device can''t perform',20); pp20(' commanded action   ',17) end;
cbound:    begin pp20('ARM Code compute bou',20); pp5('nd!  ',3) end;
featna:    begin pp20('Feature not availabl',20); pp10('e yet.    ',6) end;
otherwise  begin pp20('Unknown error! =    ',17); ppInt(ord(err)) end;
    end;
   badJoints(angle);     (* tell which joint(s) were bad, if any *)
   end;
end;

(* doSay called by Interp *)

procedure doSay;
 var n,np: nodep; b: boolean;

 procedure sayInt(i: integer);
  var j: integer; n: array [1..9] of integer;
  begin
  for j := 1 to 9 do		(* get individual digits *)
   begin n[j] := i mod 10; i := i div 10 end;
  j := 9;
  while (j > 1) and (n[j] = 0) do j := j - 1;	(* ignore leading zeros *)
  for i := j downto 1 do
   write(talk,chr(ord('0')+n[i]));		(* say digit *)
  end;
  
 procedure saySval(s: real);
  var si: real; ip,fp: integer;
  begin
  if s < maxInt then
    begin
    si := trunc(s);
    s := si + round(1000*(s-si))/1000;
    ip := trunc(s);
    fp := trunc(1000*(s-ip));
    sayInt(ip);				(* say integer part *)
    if fp > 0 then
      begin				(* say fractional part too *)
      write(talk,' point ');
      sayInt(fp);
      end;
    end
   else
    begin				(* it's a bignum *)
    fp := 0;
    repeat fp := fp + 1; s := s / 10 until s <= maxint;	(* scale it down *)
    sayInt(trunc(s));			(* say significant digits *)
    for ip := 1 to fp do		(* now the trailing zeros *)
     write(talk,'0');
    end;
  write(talk,' ,, ');			(* add a small pause *)
  end;

 procedure sayVec(v: vectorp);
  var i: integer;
  begin
  write(talk,' vector ');
  with v↑ do 
   for i := 1 to 3 do 
    begin
    saySval(val[i]);
    end;
  write(talk,' ,, ');			(* add a small pause *)
  end;

 procedure sayTrans(t: transp);
  var i: integer; v: vectorp;
  begin
  with t↑ do
   begin
   refcnt := refcnt + 1;
   write(talk,' trans rot ');
   v := taxis(t); sayVec(v); relVector(v);
   saySval(tmagn(t));
   write(talk,' , vector ');
   for i := 1 to 3 do
    begin
    saySval(val[i,4]);
    end;
   write(talk,' ,, ');			(* add a small pause *)
   refcnt := refcnt - 1;
   end;
  end;

 procedure sayStrng(length: integer; s: strngp);
  var i,j: integer; cntl: boolean; ch: ascii;
  begin
  j := 1;
  cntl := false;
  for i := 1 to length do
   begin
   ch := s↑.ch[j];
   if cntl then
     begin					(* make it a control char *)
     if ord(ch) >= smallA then
       ch := chr(ord(ch) - ord(' '));		(* convert to uppercase *)
     write(talk,chr(ord(ch) - ord('@')));
     cntl := false;
     end
    else if ch = '\' then cntl := true
    else
     write(talk,ch);
   if j = 10 then begin j := 1; s := s↑.next; end
    else j := j + 1;
   end;
  end;

 begin {doSay}
 with curInt↑ do
  begin				(* say whatever user wants us to *)
  n := spc↑.plist;
  while n <> nil do			(* say everything on the list *)
   begin
   np := getNval(n↑.lval,b);
   if np <> nil then
     begin
     with np↑ do
      case ltype of
 svaltype:  saySval(s);
 vectype:   sayVec(v);
 transtype: sayTrans(t);
 strngtype: sayStrng(length,str);
       end;
     if b then killNode(np);	(* flush used stack entry *)
     end;
   n := n↑.next;
   end;
  if spc↑.plist <> nil then
    begin
    writeln(talk);
    break(talk);		(* say it now *)
    end;
  mode := 0;
  spc := spc↑.next;
  end;
 end;

(* doArmmagic called by Interp *)

procedure doArmmagic;
 var e: enventryp; ev: eventp; np: nodep; i,j,k: integer;
 begin
 with curInt↑ do
  case mode of
1:  begin
    np := pop;
    i := round(np↑.s);		(* get # of arm magic command *)
    relNode(np);
    e := gtVarn(spc↑.dev);	(* remember what we're moving *)
    mech := e↑.f;
    ev := getEvent;	(* event to use for signalling when motion finishes *)
    ev↑.count := -1;
    ev↑.waitlist := curInt;
    j := 0;
    np := spc↑.iargs;
    while np <> nil do begin np := np↑.next; j := j + 1 end;	(* count args *)
    with msg↑ do
     begin
     cmd := armmagiccmd;
     n := i;				(* command number *)
     dev := getMechbits;
     bits := j;
     evt := ev;
     sendCmd;				(* initiate the armmagic operation *)
     for i := 1 to j do
      begin				(* send over the arguments *)
      np := pop;			(* get next argument *)
      if np↑.ltype = svaltype then
	begin
	cmd := realcmd;
	dur := np↑.s
	end
       else if np↑.ltype = vectype then
	begin
	cmd := vectorcmd;
	with np↑.v↑ do
	 begin
	 v1 := val[1];			(* copy vector *)
	 v2 := val[2];
	 v3 := val[3];
	 end
	end
       else if np↑.ltype = transtype then
	begin
	cmd := transcmd;
	with np↑.t↑ do
	 begin
	 for k := 1 to 3 do begin t[k] := val[k,1]; t[k+3] := val[k,2] end;
	 sendCmd;			(* send first packet of trans over *)
	 for k := 1 to 3 do begin t[k] := val[k,3]; t[k+3] := val[k,4] end;
	 end;
	end
       else
	begin			(* error -- must be string type *)
	pp20L('ARM MAGIC can''t hand',20); pp10('le strings',10); ppLine;
	cmd := realcmd;
	dur := 0.0;			(* send a zero instead *)
	end;
      sendCmd;			(* send real/vector/2nd-half-of-trans over *)
      killNode(np);			(* flush used stack entry *)
      end;
     end;
    signalArm;				(* start things happening *)

    mode := 2;
    status := devicewait;
    curInt := nil;
    resched := true;			(* swap someone else in *)
    end;

2:  begin
    mode := 0;				(* get ready for next statement *)
    spc := spc↑.next;
    end

   end;

end;

(* doFloat called by Interp *)

procedure doFloat;
 var mechbits: integer; e: enventryp; cl,load,val1: nodep; b: boolean;
 begin
 with curInt↑ do
  begin
  load := nil;
  cl := spc↑.clauses;
  while cl <> nil do			(* look for LOAD clause *)
   with cl↑ do
    begin
    if ntype = loadnode then load := cl;
    cl := next;
    end;

  if spc↑.cf = nil then mechbits := GARMDEV		(* assume GARM *)
   else
    begin
    e := gtVarn(spc↑.cf);		(* see what we're floating *)
    with e↑.f↑ do
     if ftype then
       if dev <> nil then mechbits := dev↑.mech
	else
	 begin		(* yow! frame that's not affixed to a device *)
	 pp20L('Attempt to float a f',20); pp20('rame not affixed to ',20);
	 pp20('any device: Assuming',20); pp5(' GARM',5); ppLine;
	 mechbits := GARMDEV;
	 end
      else mechbits := mech;
    end;

  if load <> nil then
    with msg↑ do				(* indicate load for arm *)
     begin
     cmd := setloadcmd;
     if load↑.lcsys then bits := FTABLE	(* in World or Hand? *)
      else bits := FHAND;
     val1 := getNval(load↑.loadval,b);		(* mass of load *)
     dur := val1↑.s;
     if b then relnode(val1);
     if load↑.loadvec <> nil then
       begin
       val1 := getNval(load↑.loadvec,b);	(* where load is located *)
       with val1↑.v↑ do
	begin v1 := val[1]; v2 := val[2]; v3 := val[3] end;
       if b then relnode(val1);
       end
      else begin v1 := 0; v2 := 0; v3 := 0 end;
     sendCmd;					(* tell ARM about the load *)
     end;

  with msg↑ do
   begin
   cmd := floatcmd;
   if load <> nil then bits := Loadcb else bits := 0;
   dev := mechbits;
   end;
  beep;		(* beep the terminal to warn that a float is about to start *)
  sendCmd;				(* tell arm servo to float device *)

  mode := 0;
  spc := spc↑.next;
  end;
 end;